import threadpool, time, threading
from concurrent.futures import ThreadPoolExecutor,as_completed

# def sayhello(name):
#     print("%s say Hello to %s" % (threading.current_thread().getName(), name));
#     time.sleep(1)
#     return name
#
# def callback(request, result): # 回调函数，用于取回结果
#     print("callback result = %s" % result)
#
# pool.putRequest() 将任务丢到线程池执， pool.wait() 等待所有线程结束。同时我们还可以定义回调函数，拿到任务的返回结果
# name_list =['admin','root','scott','tiger']
# start_time = time.time()
# pool = threadpool.ThreadPool(2) # 创建线程池
# requests = threadpool.makeRequests(sayhello, name_list, callback) # 创建任务
# [pool.putRequest(req) for req in requests] # 加入任务
# pool.wait()
# print('%s cost %d second' % (threading.current_thread().getName(), time.time()-start_time))

# TODO ThreadPoolExecutor 方式
'''
ThreadPoolExecutor 是 python3 新引入的库，具体使用方法与 threadpool 大同小异，
同样是创建容量为 2 的线程池，提交四个任务。只不过这里分别是通过 submit 和 as_completed 来提交和获取任务返回结果的
'''

def sayhello(name):
    print("%s say Hello to %s" % (threading.current_thread().getName(), name));
    time.sleep(1)
    return name

name_list =['admin','root','scott','tiger']
start_time = time.time()
with ThreadPoolExecutor(2) as executor: # 创建 ThreadPoolExecutor
    future_list = [executor.submit(sayhello, name) for name in name_list] # 提交任务

for future in as_completed(future_list):
    result = future.result() # 获取任务结果
    print("%s get result : %s" % (threading.current_thread().getName(), result))

print('%s cost %d second' % (threading.current_thread().getName(), time.time()-start_time))

'''
常用的两种线程池的实现方式，在多线程编程中能使用线程池就不要自己去创建线程，并不是说线程池实现的多么好，其实我们自己完全也可以实现一个功能更强大的线程池。
但是其内置的线程池一来是受过全方面测试的，在安全性，性能和方便性上基本就是最优的了，
同时线程池还替我们做了很多额外的工作，比如任务队列的维护，线程销毁时资源的回收等都不需要开发者去关心，
我们只需注重业务逻辑即可，不需要在关心其他额外的工作，这将大大提高我们的的工作效率和使用感受。

当然其自带的线程池也不是十全十美的，至少暂时没有提供动态添加任务的入口出来。而且在设计方面不够灵活，
比如我想线程池只维护一个核心数量，也就是上文说的最大数量。但是当任务过多时可以再额外创建出一些新的线程（阈值可以自定义），
处理完之后这些多余的线程将自动销毁，目前这个是做不到的。
'''